﻿using System.Collections.Generic;
using Core.Domain;
using Core.Domain.Lexems;
using Core.SyntaxAnalysis;
using Core.SyntaxAnalysis.Classes;

namespace Core
{
    public class Env
    {
        private static readonly Dictionary<string, Identificator> variables = new Dictionary<string, Identificator>();
        private static readonly Dictionary<string, Label> labels = new Dictionary<string, Label>();
        private static int labelCounter = 10;
        private static int variableCounter = 10;
        private static string varCharh = "t";

        private static readonly Dictionary<string, List<DataType>> m_functions = new Dictionary<string, List<DataType>>
                                                                                 {
                                                                                     {"WRITE", new List<DataType> {new Float(), new Float()}},
                                                                                     {"WRITELN", new List<DataType> {new Float()}},
                                                                                     {"READ", new List<DataType> {new Float()}},
                                                                                     {"READLN", new List<DataType> {new Float(), new Integer()}}
                                                                                 };

        public static Identificator FindId(Lexem lex)
        {
            string lex_str = lex.StrValue;
            if (variables.ContainsKey(lex_str))
            {
                return variables[lex_str];
            }
            else
            {
                return null;
            }
        }

        public static Identificator AddId(Lexem lex)
        {
            string lex_str = lex.StrValue;
            if (variables.ContainsKey(lex_str))
            {
                return variables[lex_str];
            }
            else
            {
                var id = new Identificator(lex);
                variables.Add(lex_str, id);
                return id;
            }
        }

        public static Label FindLabel(Lexem lex)
        {
            string lex_str = lex.StrValue;
            if (labels.ContainsKey(lex_str))
            {
                return labels[lex_str];
            }
            else
            {
                return null;
            }
        }

        public static Label AddLabel(Lexem lex, Stmt after)
        {
            string lex_str = lex.StrValue;
            var id = new Label(lex, after);
            if (!labels.ContainsKey(lex_str))
            {
                labels.Add(lex_str, id);
            }
            return id;
        }

        public static int NextLabel()
        {
            while (labels.ContainsKey(labelCounter.ToString()))
            {
                labelCounter++;
            }
            int t = labelCounter;
            labelCounter++;
            return t;
        }

        public static string NextVariable()
        {
            while (variables.ContainsKey(varCharh + variableCounter))
            {
                variableCounter++;
            }
            string s = varCharh + variableCounter;
            variableCounter++;
            return s;
        }

        public static void Clear()
        {
            variables.Clear();
            labels.Clear();
            labelCounter = 10;
            variableCounter = 10;
        }

        public static List<DataType> GetPrototype(string funcName)
        {
            return m_functions.ContainsKey(funcName.ToUpper()) ? m_functions[funcName] : null;
        }
    }
}